package biblioteca.modelos;

import biblioteca.entidades.*;
import biblioteca.excepciones.ExcepcionDeAplicacion;
import biblioteca.excepciones.ExcepcionDeBD;
import java.util.ArrayList;
import poo.biblioteca.bd.BDLibros;

public class MdlLibros {

    BDLibros bdLibros = new BDLibros();

    public ArrayList<Libro> buscarLibro(String isbn, String titulo, Editorial editorial,
            Genero genero) throws ExcepcionDeAplicacion {
        
        if (titulo!=null && titulo.length()<2)
            throw new ExcepcionDeAplicacion("Las búsquedas deben realizarse con al menos dos letras del título");
        
        ArrayList<Libro> coincidencias = null;

        try {
            coincidencias =
                    bdLibros.buscarLibro(isbn, titulo, editorial, genero);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }


        return coincidencias;
    }

    public void registrarGenero(Genero nuevoGenero) throws ExcepcionDeAplicacion {
        verificarFormatoGenero(nuevoGenero);


        try {
            bdLibros.registrarGenero(nuevoGenero);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public ArrayList<Genero> buscarGeneroPorNombre(String nombre) throws ExcepcionDeAplicacion {
        ArrayList<Genero> coincidencias = null;

        try {
            coincidencias = bdLibros.buscarGeneroPorNombre(nombre);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
        return coincidencias;
    }

    public void verificarFormatoGenero(Genero nuevoGenero) throws ExcepcionDeAplicacion {

        if (nuevoGenero.getNombreGenero() == null
                || nuevoGenero.getNombreGenero().trim().isEmpty()) {
            throw new ExcepcionDeAplicacion(
                    "El nombre del Género no puede estar vacío");
        }

        if (nuevoGenero.getNombreGenero().length() > 45) {
            throw new ExcepcionDeAplicacion(
                    "El nombre del Género no puede tener más de 45 "
                    + "caracteres de largo");
        }

        for (Genero genero : buscarGeneroPorNombre(nuevoGenero.getNombreGenero())) {
            if (genero.getNombreGenero().equalsIgnoreCase(nuevoGenero.getNombreGenero())) {
                throw new ExcepcionDeAplicacion("El género " + nuevoGenero.getNombreGenero()
                        + " ya se encuentra registrado.");
            }
        }

    }

    public void eliminarGenero(Genero generoSeleccionado) throws ExcepcionDeAplicacion {
        try {
            bdLibros.eliminarGenero(generoSeleccionado);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public void modificarGenero(Genero generoSeleccionado) throws ExcepcionDeAplicacion {
        try {
            verificarFormatoGenero(generoSeleccionado);
            bdLibros.modificarGenero(generoSeleccionado);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public ArrayList<Pais> listarPaises() throws ExcepcionDeAplicacion {
        try {
            return bdLibros.listarPaises();
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public void registrarEditorial(Editorial nuevaEditorial) throws ExcepcionDeAplicacion {
        verificarFormatoEditorial(nuevaEditorial);

        try {
            bdLibros.registrarEditorial(nuevaEditorial);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    private void verificarFormatoEditorial(Editorial nuevaEditorial) throws ExcepcionDeAplicacion {
        if (nuevaEditorial.getNombreEditorial() == null
                || nuevaEditorial.getNombreEditorial().trim().isEmpty()) {
            throw new ExcepcionDeAplicacion(
                    "El nombre de la Editorial no puede estar vacío");
        }

        if (nuevaEditorial.getNombreEditorial().length() > 100) {
            throw new ExcepcionDeAplicacion(
                    "El nombre de la Editorial no puede tener más de 100 "
                    + "caracteres de largo");
        }

        for (Editorial editorial : buscarEditorialPorNombre(nuevaEditorial.getNombreEditorial())) {
            if (editorial.getNombreEditorial().equalsIgnoreCase(nuevaEditorial.getNombreEditorial())) {
                throw new ExcepcionDeAplicacion("La Editorial " + nuevaEditorial.getNombreEditorial()
                        + " ya se encuentra registrada");
            }
        }
    }

    public ArrayList<Editorial> buscarEditorialPorNombre(String nombreEditorial) throws ExcepcionDeAplicacion {
        ArrayList<Editorial> coincidencias = null;

        try {
            coincidencias = bdLibros.buscarEditorialPorNombre(nombreEditorial);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
        return coincidencias;
    }

    public void eliminarEditorial(Editorial editorialSeleccionada) throws ExcepcionDeAplicacion {
        try {
            bdLibros.eliminarEditorial(editorialSeleccionada);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public void modificarEditorial(Editorial editorialSeleccionada) throws ExcepcionDeAplicacion {
        try {
            verificarFormatoEditorial(editorialSeleccionada);
            bdLibros.modificarEditorial(editorialSeleccionada);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public void registrarAutor(Autor nuevoAutor) throws ExcepcionDeAplicacion {
        verificarFormatoAutor(nuevoAutor);
        try {
            bdLibros.registrarAutor(nuevoAutor);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public void verificarFormatoAutor(Autor nuevoAutor) throws ExcepcionDeAplicacion {
        if (nuevoAutor.getNombreAutor() == null
                || nuevoAutor.getNombreAutor().trim().isEmpty()) {
            throw new ExcepcionDeAplicacion(
                    "El nombre del Autor no puede estar vacío");
        }
        if (nuevoAutor.getApellidoAutor() == null
                || nuevoAutor.getApellidoAutor().trim().isEmpty()) {
            throw new ExcepcionDeAplicacion(
                    "El apellidos del Autor no puede estar vacío");
        }

        if (nuevoAutor.getNombreAutor().length() > 100) {
            throw new ExcepcionDeAplicacion(
                    "El nombre del Autor no puede tener más de 100 "
                    + "caracteres de largo");
        }

        if (nuevoAutor.getApellidoAutor().length() > 100) {
            throw new ExcepcionDeAplicacion(
                    "El apellido del Autor no puede tener más de 100 "
                    + "caracteres de largo");
        }

        for (Autor autor : buscarAutorPorNombreYApellido(nuevoAutor.getNombreAutor(),
                nuevoAutor.getApellidoAutor())) {
            if (autor.getNombreAutor().equalsIgnoreCase(nuevoAutor.getNombreAutor())) {
                throw new ExcepcionDeAplicacion("El Autor " + nuevoAutor.getNombreAutor()
                        + " ya se encuentra registrado");
            }
        }
    }

    public ArrayList<Autor> buscarAutorPorNombreYApellido(String nombreAutor,
            String apellidoAutor) throws ExcepcionDeAplicacion {

        ArrayList<Autor> coincidencias = null;

        try {
            coincidencias = bdLibros.buscarAutorPorNombreYApellido(nombreAutor, apellidoAutor);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
        return coincidencias;
    }

    public void eliminarAutor(Autor autorSeleccionado) throws ExcepcionDeAplicacion {
        try {
            bdLibros.eliminarAutor(autorSeleccionado);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public void modificarAutor(Autor autorSeleccionado) throws ExcepcionDeAplicacion {
        try {
            verificarFormatoAutor(autorSeleccionado);
            bdLibros.modificarAutor(autorSeleccionado);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public void registrarLibro(Libro nuevoLibro) throws ExcepcionDeAplicacion {
        verificarFormatoLibro(nuevoLibro);
        try {
            bdLibros.registrarLibro(nuevoLibro);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    private void verificarFormatoLibro(Libro nuevoLibro) throws ExcepcionDeAplicacion {
        //ISBN
        if (nuevoLibro.getIsbn() == null
                || nuevoLibro.getIsbn().trim().isEmpty()) {
            throw new ExcepcionDeAplicacion(
                    "El ISBN no puede estar vacío");
        }
        if (nuevoLibro.getIsbn().length() > 17) {
            throw new ExcepcionDeAplicacion(
                    "El número ISBN incluyendo guiones no debe tener mas de "
                    + "17 caracteres");
        }
        if (nuevoLibro.getIsbn().length() > 17) {
            throw new ExcepcionDeAplicacion(
                    "El número ISBN incluyendo guiones no debe tener mas de "
                    + "17 caracteres");
        }
        //TITULO
        if (nuevoLibro.getTitulo() == null
                || nuevoLibro.getTitulo().trim().isEmpty()) {
            throw new ExcepcionDeAplicacion(
                    "El Título no puede estar vacío");
        }
        if (nuevoLibro.getTitulo().length() > 100) {
            throw new ExcepcionDeAplicacion(
                    "El Título no puede tener más de 100 caracteres");
        }
        //Autores
        if (nuevoLibro.getAutores().size() == 0) {
            throw new ExcepcionDeAplicacion(
                    "El libro debe tener al menos un Autor");
        }

    }

    public void eliminarLibro(Libro libroSeleccionado) throws ExcepcionDeAplicacion {
        try {
            bdLibros.eliminarLibro(libroSeleccionado);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public void modificarLibro(Libro nuevoLibro) throws ExcepcionDeAplicacion {
        verificarFormatoLibro(nuevoLibro);
        try {
            bdLibros.modificarLibro(nuevoLibro);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public int registrarEjemplar(Libro libroSeleccionado) throws ExcepcionDeAplicacion{
         try {
            return bdLibros.registrarEjemplar(libroSeleccionado);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

    public ArrayList<Ejemplar> buscarEjemplaresDisponiblesParaLibro(Libro libroSeleccionado) throws ExcepcionDeAplicacion {
        try {
            return bdLibros.buscarEjemplaresDisponiblesParaLibro(libroSeleccionado);
        } catch (ExcepcionDeBD ex) {
            throw new ExcepcionDeAplicacion(ex.getMessage());
        }
    }

}